The namegen5 website.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

192 lines
4.7 KiB

3 years ago
  1. <script context="module">
  2. export function preload({params}) {
  3. return this.fetch(`${params.name}.json`).then(r => r.json()).then(({name, collection, error}) => {
  4. return { name, collection };
  5. });
  6. }
  7. </script>
  8. <script>
  9. import { onMount } from "svelte";
  10. import capitalize from "capitalize";
  11. import Page from "../components/Page.svelte";
  12. import Selector from "../components/Selector.svelte";
  13. export let name;
  14. export let collection;
  15. /** @type {import("../rust/namegen-wasm").default} */
  16. let generator = null;
  17. let selectedSuffix = "";
  18. let selectedFormat = "";
  19. let generatedFormat = "";
  20. let generatedSuffix = "";
  21. let result = ""
  22. let failed = false;
  23. let buffer = [];
  24. let formats = [];
  25. let suffixes = [];
  26. let loaded = "";
  27. let mounted = false;
  28. function reload() {
  29. loaded = name.name;
  30. import("../rust/namegen-wasm").then(({load, default: NameGenerator}) => {
  31. return load().then(() => {
  32. console.log("Setting up", name.name);
  33. generator = new NameGenerator(name.data);
  34. })
  35. }).catch(() => {
  36. failed = true;
  37. }).finally(() => {
  38. loaded = name.name;
  39. })
  40. }
  41. function generate() {
  42. if (loaded !== name.name) {
  43. return;
  44. }
  45. let format = `${selectedFormat}:${selectedSuffix}`;
  46. if (!name.data.formats.find(f => f.name === format)) {
  47. format = selectedFormat;
  48. }
  49. if (!name.data.formats.find(f => f.name === format)) {
  50. return;
  51. }
  52. if (generator !== null) {
  53. if (buffer.length === 0) {
  54. console.time("Generate 64 names");
  55. buffer = generator.generateMany(format, 64);
  56. console.timeEnd("Generate 64 names");
  57. }
  58. result = buffer.pop();
  59. } else {
  60. result = name.examples[format][Math.floor(Math.random() * name.examples[format].length)]
  61. }
  62. generatedFormat = selectedFormat;
  63. generatedSuffix = selectedSuffix;
  64. }
  65. onMount(() => {
  66. mounted = true;
  67. })
  68. $: {
  69. if (mounted && loaded !== name.name) {
  70. generator = null;
  71. buffer = [];
  72. generatedFormat = "";
  73. generatedSuffix = "";
  74. selectedFormat = "";
  75. selectedSuffix = "";
  76. reload();
  77. }
  78. }
  79. $: {
  80. if (mounted && (selectedFormat !== generatedFormat || selectedSuffix !== generatedSuffix)) {
  81. buffer = [];
  82. generate();
  83. }
  84. }
  85. $: {
  86. const formatNames = name.data.formats.map(f => f.name.split(":")[0]).filter((f, i, a) => !a.slice(0, i).includes(f));
  87. const suffixNames = name.data.formats.map(s => s.name.split(":")[1]).filter(s => s).filter((s, i, a) => !a.slice(0, i).includes(s));
  88. const formatLabels = formatNames.map(n => name.metadata[`formatLabel_${n}`] || n.split("_").map(t => capitalize(t)).join(" "));
  89. const suffixLabels = suffixNames.map(n => name.metadata[`formatSuffixLabel_${n}`] || n.split("_").map(t => capitalize(t)).join(" "));
  90. formats = formatNames.map((n, i) => ({value: n, text: formatLabels[i]}));
  91. suffixes = suffixNames.map((n, i) => ({value: n, text: suffixLabels[i]}));
  92. }
  93. </script>
  94. <svelte:head>
  95. <title>{name.metadata.name} - Namegen 5</title>
  96. </svelte:head>
  97. <Page collection={collection} selected={name.name}>
  98. <div class="name">
  99. <h1>{name.metadata.name}</h1>
  100. <div class="cateogry">{name.metadata.category}</div>
  101. <div class="description">{name.metadata.description || ""}</div>
  102. <div style="color: {name.metadata.color || "#eeeeee"}" class:long={result.length > 25} class="result">{result}</div>
  103. {#if (failed)}
  104. <div class="failed">Your browser does not support Webassembly, the generator will only pick one out of 30 examples.</div>
  105. {/if}
  106. {#if suffixes.length > 0}
  107. <Selector color={name.metadata.color} bgcolor={name.metadata.bgcolor} label={name.metadata.formatSuffixType} options={suffixes} bind:value={selectedSuffix} />
  108. {/if}
  109. <Selector color={name.metadata.color} bgcolor={name.metadata.bgcolor} label="Format" prefer="full_" options={formats} bind:value={selectedFormat} />
  110. <button disabled={(loaded !== name.name) && !failed} on:click={generate}>Generate</button>
  111. <div class="footnote">{name.metadata.footnote || ""}</div>
  112. </div>
  113. </Page>
  114. <style>
  115. h1 {
  116. text-align: center;
  117. margin-bottom: 0;
  118. line-height: 1em;
  119. }
  120. div.failed {
  121. color: #fc1;
  122. font-size: 0.9em;
  123. }
  124. div.footnote {
  125. font-size: 0.9em;
  126. color: #555;
  127. margin-top: 2em;
  128. }
  129. div.footnote:empty {
  130. display: none;
  131. }
  132. div.cateogry {
  133. font-size: 0.75em;
  134. opacity: 0.75;
  135. margin-bottom: 1em;
  136. }
  137. div.result {
  138. border: 1px solid #000;
  139. border-radius: 0.5em;
  140. background-color: #333;
  141. padding: 0.5em 0;
  142. color: #eee;
  143. text-align: center;
  144. font-size: 1.5em;
  145. min-height: 1.5em;
  146. }
  147. div.result.long {
  148. font-size: 1.25em;
  149. padding: 0.75em 0;
  150. }
  151. button {
  152. background: #333;
  153. outline: none;
  154. border: 1px solid #000;
  155. color: #ccc;
  156. padding: 0.25em 1ch;
  157. margin: 1.5em 0 0.5em 0;
  158. font-size: 1.5em;
  159. }
  160. button:hover {
  161. color: #fff;
  162. }
  163. button:active {
  164. background: #444;
  165. }
  166. </style>